#include "03_header.h"

void readInput(char *buffer, int size, const char *prompt) {
    printf("%s", prompt);
    fgets(buffer, size, stdin);
    
    // 移除末尾的换行符
    size_t len = strlen(buffer);
    if (len > 0 && buffer[len-1] == '\n') {
        buffer[len-1] = '\0';
    }
}

int main(int argc, char *argv[]){                                  
    //预期输入:
    //./client 192.168.174.128(本机ip) 12345(port)
    ARGS_CHECK(argc, 3);
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));    
    ERROR_CHECK(ret, -1, "connect");

    //    int authOption; //根据标准输入录入选择注册/登录/注销
    //    char username[256] = {0};
    //    char passwd[256] = {0};

    //    printf("请选择操作：\n");
    //    printf("1. 注册\n");
    //    printf("2. 登录\n");
    //    printf("3. 注销\n");
    //    scanf("%d", &authOption);
    //    getchar(); // 消耗换行符
    //
    //    switch (authOption) {
    //        case 1: // 注册
    //            readInput(username, sizeof(username), "请输入用户名: ");
    //            readInput(passwd, sizeof(passwd), "请输入密码: ");
    //            if (signAndAuthPasswd(sockfd, username, passwd, 1) == 0) {
    //                printf("注册成功，已为你自动登录\n");
    //            } else {
    //                printf("注册失败\n");
    //                close(sockfd);
    //                return -1;
    //            }
    //            break;
    //        case 2: // 登录
    //            readInput(username, sizeof(username), "请输入用户名: ");
    //            readInput(passwd, sizeof(passwd), "请输入密码: ");
    //            if (signAndAuthPasswd(sockfd, username, passwd, 0) == 0) {
    //                printf("登录成功\n");
    //            } else {
    //                printf("登录失败\n");
    //                close(sockfd);
    //                return -1;
    //            }
    //            break;
    //        case 3: // 注销
    //            readInput(username, sizeof(username), "请输入要注销的用户名: ");
    //            if (signAndAuthPasswd(sockfd, username, "DELETE_ACCOUNT", 2) == 0) {
    //                printf("注销成功\n");
    //            } else {
    //                printf("注销失败\n");
    //                close(sockfd);
    //                return -1;
    //            }
    //            close(sockfd);
    //            return 0;
    //        default:
    //            printf("无效选项\n");
    //            close(sockfd);
    //            return -1;
    //    }


    //connect success.
    //tcp连接成功 
    //printf("connection success! please input signup or login.\n");
    ////执行注册登录需要先准备的变量
    //int authOption; //根据标准输入录入选择注册/登录/注销
    //char username[256] = {0};
    //char passwd[256] = {0};
    //printf("请选择操作：\n");
    //printf("1. 注册\n");
    //printf("2. 登录\n");
    //printf("3. 注销\n");
    //scanf("%d", &authOption);
    //getchar(); // 消耗换行符

    //switch (authOption) {
    //    case 1: // 注册
    //        readInput(username, sizeof(username), "请输入用户名: ");
    //        readInput(passwd, sizeof(passwd), "请输入密码: ");
    //        if (signAndAuthPasswd(sockfd, username, passwd, 1) == 0) {
    //            printf("注册成功，已为你自动登录\n");
    //        } else {
    //            printf("注册失败\n");
    //            close(sockfd);
    //            return -1;
    //        }
    //        break;
    //    case 2: // 登录
    //        readInput(username, sizeof(username), "请输入用户名: ");
    //        readInput(passwd, sizeof(passwd), "请输入密码: ");
    //        if (signAndAuthPasswd(sockfd, username, passwd, 0) == 0) {
    //            printf("登录成功\n");
    //        } else {
    //            printf("登录失败\n");
    //            close(sockfd);
    //            return -1;
    //        }
    //        break;
    //    case 3: // 注销
    //        readInput(username, sizeof(username), "请输入要注销的用户名: ");
    //        if (signAndAuthPasswd(sockfd, username, "DELETE_ACCOUNT", 2) == 0) {
    //            printf("注销成功\n");
    //        } else {
    //            printf("注销失败\n");
    //            close(sockfd);
    //            return -1;
    //        }
    //        close(sockfd);
    //        return 0;
    //    default:
    //        printf("无效选项\n");
    //        close(sockfd);
    //        return -1;
    //}


    //char username[100];//承接输入的用户名
    //char password[100];//承接输入的密码
    //char buf[1024];//承接输入的虚拟目录
    //char filename[1024];//承接输入的文件名
    //char cPath[1024];//承接服务端工作目录
    //int size_request = 0;//承接指令长度
    //bzero(username, 100);
    //bzero(password, 100);
    //bzero(buf, 1024);
    //bzero(filename, 1024);
    //bzero(cPath, 1024);

    //scanf(" %[^\n]", buf);//开始读取指令。忽略实际内容前的空格，一直读取到换行为止

    //if(strcmp(buf, "signup") == 0){
    //    //进行注册操作
    //    printf("please input your username : \n");
    //    scanf(" %[^\n]", username);//录入用户名
    //    printf("please input your password : \n");
    //    scanf(" %[^\n]", password);//录入密码
    //    //send username[] and password[] to server.
    //    return 0;//注册结束后退出程序
    //}

    //if(strcmp(buf, "login") == 0){
    ////进行登陆操作
    //printf("please input your username : \n");
    //scanf(" %[^\n]", username);//录入用户名
    //printf("please input your password : \n");
    //scanf(" %[^\n]", password);//录入密码
    //printf("login success! welcome %s, please input your request, press 'h' for help, 'q' for quit.\n", username);
    //}

    while(1){
        printf("connection success! please input signup, login or delete.\n");
        char username[255];//承接输入的用户名
        char password[255];//承接输入的密码
        char buf[1024];//承接输入的虚拟目录
        char filename[1024];//承接输入的文件名
        char cPath[1024];//承接客户端工作目录
        int size_request = 0;//承接指令长度
        train_t train;//承接服务端发来字符串
        char sPath[1024];//承接服务端处理后的数据
        bzero(&train, sizeof(train_t));
        bzero(sPath, 1024);
        bzero(username, 255);
        bzero(password, 255);
        bzero(buf, 1024);
        bzero(filename, 1024);
        bzero(cPath, 1024);

        scanf(" %[^\n]", buf);//开始读取指令。忽略实际内容前的空格，一直读取到换行为止

        if(strcmp(buf, "signup") == 0){
            //进行注册操作
            printf("please input your username : \n");
            scanf(" %[^\n]", username);//录入用户名
            printf("please input your password : \n");
            scanf(" %[^\n]", password);//录入密码
                                       //send username[] and password[] to server.
            printf("username = %s, password = %s.\n", username, password);
            int ret = signAndAuthPasswd(sockfd, username, password, buf);
            if(ret == -1){
                printf("request failed.\n");
                exit(-1);
            }
            //注册完成后同时进行登录
            printf("login success! welcome %s, please input your request, press 'h' for help, 'q' for quit.\n", username);
        }

        if(strcmp(buf, "delete") == 0){
            //进行注销操作
            printf("please input the username you would like to delete : \n");
            scanf(" %[^\n]", username);//录入用户名
                                       //send username[] and password[] to server.
            int ret = signAndAuthPasswd(sockfd, username, password, buf);
            if(ret == -1){
                printf("request failed.\n");
                exit(-1);
            }
            printf("delete user %s success!\n", username);
            continue;
        }
        if(strcmp(buf, "login") == 0){
            //进行登陆操作
            printf("please input your username : \n");
            scanf(" %[^\n]", username);//录入用户名
            printf("please input your password : \n");
            scanf(" %[^\n]", password);//录入密码
            int ret = signAndAuthPasswd(sockfd, username, password, buf);
            if(ret == -1){
                printf("request failed.\n");
                exit(-1);
            }
            printf("login success! welcome %s, please input your request, press 'h' for help, 'q' for quit.\n", username);
        }

        while(1){
            bzero(&train, sizeof(train_t));
            bzero(sPath, 1024);
            bzero(buf, 1024);
            bzero(cPath, 1024);
            bzero(filename, 1024);//解析指令所需结构在循环内额外初始化一次
            scanf(" %[^\n]", buf);//开始读取指令。忽略实际内容前的空格，一直读取到换行为止
            size_request = 0;//承接指令长度
            for(int i = 0; i < 1024; i ++){
                if(buf[i] != '\0'){
                    size_request ++;
                }
                else{
                    break;
                }
            }//指令长度录入结束
            if(strcmp(buf, "h") == 0){
                printf("user is seeking for help.\n");
                continue;
            }
            if(strcmp(buf, "q") == 0){
                printf("user is seeking for quit.\n");
                break;
            }//'h'，'q'指令处理结束
            char *token = strtok(buf, " ");

            if(strcmp(token, "cd") == 0){//CD指令
                token = strtok(NULL, " ");//承接空格后的第二段(即虚拟目录)
                //do something
                int ret = sendRequest(sockfd, token, CD);
                if(ret == -1){
                    printf("request failed.\n");
                    continue;
                }
                recvRequest(sockfd, &train);
                if(strcmp(train.value, "SUCCESS") == 0){
                }
                continue;
            }
            if(strcmp(token, "ls") == 0){//LS指令
                //do something
                //需要接收服务端发送的文件名字符串
                sendRequest(sockfd, token, LS);
                recvRequest(sockfd, &train);
                //开始切割，按照约定的方法切割开后发送给用户
                token = strtok(train.value, " ");
                while(token != NULL){
                    strcpy(sPath, token);
                    token = strtok(NULL, " ");
                    printf("%s ", sPath);
                }//切割完成后离开循环
                printf("\n");
                continue;
            }
            if(strcmp(token, "pwd") == 0){//PWD指令
                //do something
                sendRequest(sockfd, token, PWD);
                recvRequest(sockfd, &train);
                //需要接收服务端发送的目录字符串
                printf("%s\n", train.value);
                continue;
            }
            if(strcmp(token, "mkdir") == 0){//MKDIR指令
                strcpy(filename, strtok(NULL, " "));//承接空格后的第二段(即文件名)
                //do something
                int ret = sendRequest(sockfd, filename, MKDIR);
                if(ret == -1){
                    printf("request failed.\n");
                    continue;
                }
                continue;
            }
            if(strcmp(token, "puts") == 0){//PUTS指令
                strcpy(filename, strtok(NULL, " "));
                getcwd(cPath, 1024);//录入工作目录
                strcat(cPath, filename);
                //传递指令和文件名
                sendRequest(sockfd, filename, PUTS);
                //上传文件函数
                //准备传入结构体
                TLV tlv;
                bzero(&tlv, 256);
                strcpy(tlv.data, filename);
                client_puts_file(sockfd, &tlv, filename);

                continue;
            }
            if(strcmp(token, "gets") == 0){//GETS指令
                strcpy(filename, strtok(NULL, " "));
                //do something
                sendRequest(sockfd, filename, GETS);
                getcwd(cPath, 1024);//录入工作目录
                //下载文件函数
                TLV tlv;
                bzero(&tlv, sizeof(TLV));
                strcpy(tlv.data, filename);
                tlv.length = strlen(tlv.data);
                client_gets_file(sockfd, &tlv);
                continue;
            }
            if(strcmp(token, "remove") == 0){
                strcpy(filename, strtok(NULL, " "));
                //do something
                int ret = sendRequest(sockfd, filename, REMOVE);
                if(ret == -1){
                    printf("request failed.\n");
                    continue;
                }
                continue;
            }
            if(strcmp(token, "rmdir") == 0){
                strcpy(filename, strtok(NULL, " "));
                //do something
                int ret = sendRequest(sockfd, filename, RMDIR);
                if(ret == -1){
                    printf("request failed.\n");
                    continue;
                }
                continue;
            }
            else{
                printf("wrong input, please input correctly.\n");
                continue;
            }
        }
    }
    return 0;
}

